import Block from "./Block.js";
import Row from "./Row.js";

/**
 * 球  多个块组成的
 *
 * 拥有基础的树形结构
 *
 */


export default class Rd {
    constructor(){
        this.index=1;
        this.indexList=[];
        this.dict=null;
        this. current_id = 1;
        let block=new Block();
        let name=this.dictName("");
        block.addRow(new Row(0,name));
        this.list={"1":block}

    }

    next_id(){
        this.current_id++;
        while (this.list[  this.current_id]){
            this.current_id++;
        }
        return this.current_id.toString();
    }
    /**
     * 设置字典
     * @param dict Phere
     */
    put(dict){
        this.dict=dict;
    }

    /**
     * 通过过名称 返回 id 或者数字 返回
     * @param idOrNum
     * @param type
     * @returns {*}
     */
    dictName(name,type){
        if(name==""){
            return ""
        }
        if(this.dict==null){
            return  name;
        }
        return this.dict.findId(name,type)
    }

    /**
     * 通过过id 或者数字 返回名称
     * @param idOrNum
     * @param type
     * @returns {*}
     */
    dictId(idOrNum,type){
        if(this.dict==null){
            return  idOrNum;
        }
        return this.dict.findName(idOrNum,type)
    }
    /**
     * 跳转文件夹
     * @param name
     * @returns {*}
     */
    cdId(id){
        if( id == null || id ==undefined || id=="" ){
            this.index=1;
            this.indexList=[];
            return true;
        }
        let block=   this.list[id];
        if(block){
            this.index =id;
            return true;
        }

        return  false;

    }

    /**
     * 跳转文件夹
     * @param name
     * @returns {*}
     */
    cd(name){
        if( name == null || name ==undefined || name=="" ){
            this.index=1;
            this.indexList=[];
            return true;
        }
        let block=   this.list[this.index];
        for(let i=0;i<block.list.length-1;i++){
            let row= block.list[i+1]
            if( row.isValue(4,name)){
                this.index =row.find(1)
                this.indexList.push(name)
                return true;
            }
        }

        return  false;

    }

    /**
     * 搜索名称 返回id
     * @param name
     * @returns {*}
     */
    search(name){
        if( name == null || name ==undefined || name=="" ){
            return  "";
        }
        let numName=this.  findId(name);

        return  numName;
    }

    findIndex(){
        this.index;
    }


    /**
     * 获取当前目录
     */
    findCurrentDir(){
        let res=[];
        let block= this.list[this.index]

        for(let i=0;i<block.list.length-1;i++){
            let row= block.list[i+1]

            let obj={}

            if(row.isValue(3,"")){
                obj.type="0"
            }else {
                obj.type=row.find(3);
            }

            obj.name= row.find(4);
            res.push(obj)
        }

        return res
    }



    /**
     * 添加节点
     * @param name
     * @returns {*}
     */
    addNode(name,type){

        let id=this.addRow(name,"",type)
        return id;
    }


    /**
     * 是否是文件夹
     * @param name
     * @returns {*}
     */
    isDir(name){
        if( name == null || name ==undefined || name=="" ){
            return  false;
        }
        let block=   this.list[this.index];
        for(let i=0;i<block.list.length-1;i++){
            let row= block.list[i+1]
            if( row.isValue(4,name)){
                if(row.isValue(3,"")){
                    return true;
                }else {
                    return  false;
                }
            }
        }
        return  false;

    }
    delId(id){
        if(id<2){
            throw  new Error("删除id 小于2");
        }
        if(this.list[id]){

            let block=  this.list[id]
            let row= block.find(1);
            //删除 旧的pid里面的数据
            let lioPid= row.find(1);
            let lioPidBlock = this.list[lioPid];
            for (let n=1;n<lioPidBlock.list.length;n++){
                let listElement = lioPidBlock.list[n];
                if(listElement.isValue(1,id)){
                    lioPidBlock.list.splice(n, 1)
                    break;
                }
            }
            this.list[lioPid]=lioPidBlock;
            this._delId(id)
            return true
        }
        return  false;

    }
    _delId(id){

        let  block=this.list[id];
        delete  this.list[id];

        for (let n=1;n<block.list.length;n++){
            let row=block.find(n+1)
            this._delId(row.find(1));
        }

    }


    delRow(name){
        let index=this.findType() ;
        let block=   this.list[index];
        for(let i=block.list.length-1;i>0;i--){
            let row= block.list[i+1]
            if( row.isValue(4,name)){
                delete this.list[i+1];
            }
        }
    }

    saveRow(id,pid,name,value,type){


        if(pid){
            let block=   this.list[pid];

            if(!block){
                throw  new Error("找不到pid的block")
            }
            if(id!==""&&id<1){
                throw  new Error("id 不能小于1")
            }


            let block1   ;
            let row = new Row(pid,name,value,type);
            if(!id){
                id = this.next_id();

                block1= new Block()
                block1.addRow(row)
                block.addRow(new Row(id,name,value,type))
            }else {
                block1= this.list[id];
                if(block1){
                    //删除 旧的pid里面的数据
                    let lioRow = block1.list[0];
                    let lioPid= lioRow.find(1);
                    if(lioPid!=pid){
                        let lioPidBlock = this.list[lioPid];
                        for (let n=1;n<lioPidBlock.list.length;n++){
                            let listElement = lioPidBlock.list[n];
                            if(listElement.isValue(1,id)){
                                lioPidBlock.list.splice(n, 1)
                                break;
                            }
                        }
                        this.list[lioPid]=lioPidBlock;
                        block.addRow(new Row(id,name,value,type))
                    }else {
                        let lioPidBlock = this.list[lioPid];
                        for (let n=1;n<lioPidBlock.list.length;n++){
                            let listElement = lioPidBlock.list[n];
                            if(listElement.isValue(1,id)){
                                lioPidBlock.list[n]=new Row(id,name,value,type);
                                break;
                            }
                        }
                        block=   lioPidBlock;
                    }

                    block1.list[0]=row;
                }else {
                    block1= new Block()
                    block1.addRow(row)
                    block.addRow(new Row(id,name,value,type))
                }


            }


            this.list[id]= block1;

            this.list[pid]=block;
            return id ;
        }
        id = this.next_id();

         let block2= new Block()

        this.list[id]= block2;
         return  id;
    }



    eiteRow(id,name,a,type){

        let block= this.list[id];
        let row2= block.find(1);
        let pid=row2.find(1);
        let row =new Row(id,name,a,type)
        let rowp =new Row(pid,name,a,type)



        this.list[id].list[0]=rowp;
        if(0==pid){
            return true
        }

        let pblock=  this.list[pid];

        for(let i=0;i<pblock.list.length-1;i++){
            let row1= pblock.list[i+1]
            if( row1.isValue(1,id)){
                pblock.list[i+1]=row;
                this.list[pid]=pblock;
                break;
            }
        }

        return true;
    }

    addRow(name,a,type){
        let index=this.index;

        let id=this.next_id();
        this.list[id]=new Block();
        let row =new Row(id,name,a,type)
        let rowp =new Row(index,name,a,type)
        this.list[index].addRow(row)
        this.list[id].addRow( rowp);
        return id;
    }

    /**
     * 是否存在
     * @param name
     * @returns {*}
     */
    isNot(name){
        if( name == null || name ==undefined || name=="" ){
            return  false;
        }
        let block=   this.list[this.index];
        for(let i=0;i<block.list.length-1;i++){
            let row= block.list[i+1]
            if( row.is(4,name)){
                return true;
            }
        }
        return  false;

    }

    findNode(id){
        return   this.list[this.index].find(id);
    }


    //获取类型 索引
    findType(type){
        if(type==null||typeof (type)=="undefined"){
            return this.index
        }else {

            let block=   this.list[this.index];
            for(let i=0;i<block.list.length-1;i++){
                let row= block.list[i+1]
                if( row.isValue(4,type)){
                    return  row.find(1);
                }
            }

        }
        return this.index;
    }

    findName(id,type){

        let index=this.findType(type)

        let block2=   this.list[index];

        for(let i=0;i<block2.list.length-1;i++){
            let row= block2.list[i+1]
            if( row.isValue(1,id)){
                let num= row.find(4);
                let name= this.dictId(num,type)
                return   name;
            }
        }
        return  null;
    }
    findId(name,type){

        //let index=this.findType(type)
        let numName= this.dictName(name,type)
        for (var Key in this.list){
            let row= this.list[Key].find(1)
            if( row.isValue(4,numName)){
                return          Key;
            }
        }

        return  null;
    }

    /**
     *  转换成树
     * @param id
     * @returns {Array}
     */
    toTree(id){
        let block=   this.list[id]
        let res={};
        let row= block.find(1);
        res.pid=    row.find(1);
        res.type= this.dictId(row.find(2));
        res.value= this.dictId(row.find(3));
        res. name=this.dictId(row.find(4));
        res.id=id;
        if(block.list.length>1){
            let children=[];
            for(let i=1;i<block.list.length;i++) {
                let rows=   block.find(i+1);
                let resli=this.toTree( rows.find(1))
                children.push(resli)
            }
            res. children=children
        }

        return res;

    }
    toTreeNum(id){
        let block=   this.list[id];
        if(!block){
            return
        }
        let res={};
        let row= block.find(1);
        res.pid=    row.find(1).toString();
        res.type= row.find(2).toString();
        res.value= row.find(3).toString();
        res. name=row.find(4).toString();
        res.id=id;
        if(block.list.length>1){
            let children=[];
            for(let i=1;i<block.list.length;i++) {
                let rows=   block.find(i+1);
                let resli=this.toTreeNum( rows.find(1))
                children.push(resli)
            }
            res. children=children
        }

        return res;

    }

    /**
     * 保存名称
     * @param id
     * @param name
     * @param type
     * @returns {boolean}
     */
    saveName(id,name,type){
        let index=this.findType(type)
        let numName= this.dictName(name,type)

        let block=   this.list[index];
        for(let i=0;i<block.list.length-1;i++){
            let row= block.list[i+1]
            if( row.isValue(1,id)){
                row.save(4,numName)
                block.list[i+1]=row
                this.list[index]=block;
                return true;
            }
        }
        return false ;
    }

    /**
     * 保存主键
     * @param id
     * @param name
     * @param type
     * @returns {boolean}
     */
    saveId(name,id,type){
        let index=this.findType(type)
        let numName= this.dictName(name,type)
        let block=   this.list[index];
        for(let i=0;i<block.list.length-1;i++){
            let row= block.list[i+1]
            if( row.isValue(4,numName)){
                row.save(1,id)
                block.list[i+1]=row
                this.list[index]=block;
                return true;
            }
        }
        return false ;
    }



    /**
     *  加载 数据
     * @param data
     */
    loadData(data){
        let _this=this;
        let rows=[];
        let testNub="";
        this.list=[]
        for(let i=0;i<data.length;i++){
            let num=data[i].toString(2);
            let buffNum =  (Array(8).join(0) + num).slice(-8);
            let code0= parseInt(buffNum.substr(0,4),2).toString(16);
            let code1= parseInt(buffNum.substr(4,7),2).toString(16);
            testNub+=code0+code1
        }
        let list= testNub.split("c")
        let regex=/^[0]+/;
        if(list[list.length-1].toString().replace(regex,"")===""){
            list.length= list.length-1;
        }
        let headBlock=    new Block();
        headBlock.decode(list[0]);
        //索引
        let row=headBlock.find(1);
        this.current_id=row.find(4);
        for (let i=1;i<headBlock.list.length;i++){

            let row2= headBlock.find(i+1);

            let key=    row2.find(4)
            let block=    new Block();
            block.decode(list[i]);
            this.list[key]=block;
        }

    }
    outData(){
        let _this=this;
        let res=""
        let buffList=[];
        let index=0;
        let headBlock=new Block();
        headBlock.addRow(new Row(_this.current_id))
        for(let key in _this.list){
            let row =_this.list[key].encoded();
            res+=row+'c'
            index++;
            headBlock.addRow(new Row(index,key))
        }
        let headCode=headBlock.encoded();
        res=headCode+'c'+res
        let dataList =res.split("");
        if(dataList.length%2==1){ //如果如果长度单数，则在最后补1
            dataList=["0",...dataList]
        }
        for(let i=0;i<dataList.length;i=i+2){
            let num1 = parseInt(dataList[i], 16).toString(2);
            let test1 =(Array(4).join(0) + num1).slice(-4)
            let num2 = parseInt(dataList[i+1], 16).toString(2);
            let test2 =(Array(4).join(0) + num2).slice(-4)
            let text = test1+test2;
            let intcode= parseInt(text,2)
            buffList.push( intcode)
        }
        return new Uint8Array(buffList);
    }

    addBlock(block){
        let id=this.next_id();
        this.list[id]=block;
    }



    find(n){
        let res=this.list[n];
        if(typeof(res )!=="undefined" ){
            return res;
        }
        return null;
    }


    /**
     * 判断类型
     * @param id
     * @param type
     * @returns {boolean}
     */
    isRow(id,name,value,type){
        let wordBlock=    this.list[id];
        if(!wordBlock) return false;
        let list=  wordBlock.isRows("",name,value,type);
        if(list.length>0){
            return true;
        }
        return false;
    }


    /**
     * 判断类型
     * @param id
     * @param type
     * @returns {boolean}
     */
    findRow(id,name,value,type){
        let wordBlock=    this.list[id];
        if(!wordBlock){
            return new Array()
        }
        let list=  wordBlock.isRows("",name,value,type);
        return list;
    }
}
